package com.vdong.trade.order.service.statemachine;

import com.vdong.trade.order.common.contract.DisbOrderStateMachineEventContract;
import com.vdong.trade.order.common.contract.TableContract;
import com.vdong.trade.order.entity.dto.param.*;
import com.vdong.trade.order.entity.dto.result.*;
import com.vdong.trade.order.entity.po.*;
import com.vdong.trade.order.service.DisbOrderService;
import org.apache.commons.lang3.StringUtils;
import org.lamb.framework.common.util.BeanPlasticityUtill;
import org.lamb.framework.common.util.JsonUtil;
import org.lamb.framework.common.util.StringUtil;
import org.lamb.framework.statemachine.annotation.LambStateMachineListener;
import org.lamb.framework.statemachine.annotation.LambStateMachineOnTransition;
import org.lamb.framework.statemachine.container.LambStateMachineTransition;

import javax.annotation.Resource;
import java.util.Optional;


/**
 * @description: 订单服务
 * @author: Mr.WangGang
 * @create: 2018-11-20 下午 3:21
 **/

@LambStateMachineListener
public class DisbOrderListener {

    @Resource
    private DisbOrderService disbOrderService;

    @LambStateMachineOnTransition(initial = TableContract.Order.OrderStatus.DisbOrderStatus.INITIAL,
            event = DisbOrderStateMachineEventContract.DISB_CREATE,error = "该订单在创建的过程中发生了异常")
    public DisbOrderCreateResultDTO create(LambStateMachineTransition<String> transition) {
        return disbOrderService.create(cast(transition, DisbOrderCreateParamPO.class,DisbOrderCreateParamDTO.class));
    }

   /* @LambStateMachineOnTransition(source = TableContract.Order.OrderStatus.DisbOrderStatus.INITIAL, target = TableContract.Order.OrderStatus.DisbOrderStatus.UNPAID, event = DisbOrderStateMachineEventContract.DISB_APPLYPAY,error = "该订单必须是预订单才能申请支付")
    public DisbOrderApplyPayResultDTO applyPay(LambStateMachineTransition<String> transition) {
        return disbOrderService.applyPay(cast(transition, DisbOrderApplyPayParamPO.class,DisbOrderApplyPayParamDTO.class));
    }*/

    @LambStateMachineOnTransition(source = TableContract.Order.OrderStatus.DisbOrderStatus.INITIAL,
            target = TableContract.Order.OrderStatus.DisbOrderStatus.INPAID,
            event = DisbOrderStateMachineEventContract.DISB_PAY,error = "该订单必须是预订单才能申请支付")
    public DisbOrderPayResultDTO pay(LambStateMachineTransition<String> transition) {
        return disbOrderService.pay(cast(transition, DisbOrderPayParamPO.class,DisbOrderPayParamDTO.class));
    }

    @LambStateMachineOnTransition(source = TableContract.Order.OrderStatus.DisbOrderStatus.INPAID, target =
            TableContract.Order.OrderStatus.DisbOrderStatus.PAID, event = DisbOrderStateMachineEventContract.DISB_PAYDONE,
            error = "该订单必须是付款中才能结束支付")
    public DisbOrderPayDoneResultDTO payDone(LambStateMachineTransition<String> transition) throws Exception {
        return disbOrderService.payDone(cast(transition, DisbOrderPayDoneParamPO.class,DisbOrderPayDoneParamDTO.class));
    }

    @LambStateMachineOnTransition(source = TableContract.Order.OrderStatus.DisbOrderStatus.PAID,
            target = TableContract.Order.OrderStatus.DisbOrderStatus.UNREFUND,
            event = DisbOrderStateMachineEventContract.DISB_APPLYREFUND,error = "该订单必须是已付款才能申请退款")
    public DisbOrderApplyRefundResultDTO applyRefund(LambStateMachineTransition<String> transition) {
        return disbOrderService.applyRefund(cast(transition, DisbOrderApplyRefundParamPO.class,DisbOrderApplyRefundParamDTO.class));
    }

    @LambStateMachineOnTransition(source = TableContract.Order.OrderStatus.DisbOrderStatus.UNREFUND,
            target = TableContract.Order.OrderStatus.DisbOrderStatus.INREFUND,
            event = DisbOrderStateMachineEventContract.DISB_REFUND,error = "该订单必须是待退款才能进行退款")
    public DisbOrderRefundResultDTO refund(LambStateMachineTransition<String> transition) {
        return disbOrderService.refund(cast(transition, DisbOrderRefundParamPO.class,DisbOrderRefundParamDTO.class));
    }

    @LambStateMachineOnTransition(source = TableContract.Order.OrderStatus.DisbOrderStatus.INREFUND,
            target = TableContract.Order.OrderStatus.DisbOrderStatus.REFUND,
            event = DisbOrderStateMachineEventContract.DISB_REFUNDDONE,error = "该订单必须是退款中才能完结退款")
    public DisbOrderRefundDoneResultDTO refundDone(LambStateMachineTransition<String> transition) {
        return disbOrderService.refundDone(cast(transition, DisbOrderRefundDoneParamPO.class,DisbOrderRefundDoneParamDTO.class));
    }

    @LambStateMachineOnTransition(source = TableContract.Order.OrderStatus.DisbOrderStatus.INPAID,
            target = TableContract.Order.OrderStatus.DisbOrderStatus.CANCEL,
            event = DisbOrderStateMachineEventContract.DISB_CANCEL,error = "该订单必须是待付款才能取消订单")
    public DisbOrderCancelResultDTO cancel(LambStateMachineTransition<String> transition) {
        return disbOrderService.cancel(cast(transition, DisbOrderCancelParamPO.class,DisbOrderCancelParamDTO.class));
    }

    @LambStateMachineOnTransition(source = TableContract.Order.OrderStatus.DisbOrderStatus.PAID,
            target = TableContract.Order.OrderStatus.DisbOrderStatus.UNSETTLEMENT,
            event = DisbOrderStateMachineEventContract.DISB_APPLYSETTLEMENT,error = "该订单必须是已支付才能申请结算")
    public DisbOrderApplySettlementResultDTO applySettlement(LambStateMachineTransition<String> transition) {
        return disbOrderService.applySettlement(cast(transition, DisbOrderApplySettlementParamPO.class,DisbOrderApplySettlementParamDTO.class));
    }

    @LambStateMachineOnTransition(source = TableContract.Order.OrderStatus.DisbOrderStatus.UNSETTLEMENT, target = TableContract.Order.OrderStatus.DisbOrderStatus.INSETTLEMENT, event = DisbOrderStateMachineEventContract.DISB_SETTLEMENT,error = "该订单必须是待结算才能进行结算")
    public DisbOrderSettlementResultDTO settlement(LambStateMachineTransition<String> transition) {
        return disbOrderService.settlement(cast(transition, DisbOrderSettlementParamPO.class,DisbOrderSettlementParamDTO.class));
    }

    @LambStateMachineOnTransition(source = TableContract.Order.OrderStatus.DisbOrderStatus.INSETTLEMENT, target = TableContract.Order.OrderStatus.DisbOrderStatus.SETTLEMENT, event = DisbOrderStateMachineEventContract.DISB_SETTLEMENTDONE,error = "该订单必须是结算中才能完成结算")
    public DisbOrderSettlementDoneResultDTO settlementDone(LambStateMachineTransition<String> transition) {
        return disbOrderService.settlementDone(cast(transition, DisbOrderSettlementDoneParamPO.class,DisbOrderSettlementDoneParamDTO.class));
    }

    private <P,D>OrderStateMachineTransitionParamDTO<D> cast(LambStateMachineTransition<String> transition,Class<P> po,Class<D> dto){
        return (OrderStateMachineTransitionParamDTO<D>) OrderStateMachineTransitionParamDTO.builder()
                .event(transition.getEvent())
                .source(transition.getSource())
                .target(transition.getTarget())
                .data(cast(transition.getData(),po,dto)).build();
    }

    private <T,E>E cast(Optional<String> json, Class<T> po,Class<E> dto){
        if(json.isPresent()){
            if(StringUtils.isNotBlank(json.get())){
//                Optional<T> t =  JsonUtil.stringToObj(json.get(),po);
                T t = JsonUtil.toObject(json.get(), po);
                if (StringUtil.hasBlank(t)) {
                    return null;
                }
                /*if(!t.isPresent()){
                    return null;
                }*/
                return BeanPlasticityUtill.copy(dto,t);
            }
        }
        return null;
    };
}
